package com.cn.appcore.base

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import com.cn.appcore.ext.showToast
import com.cn.appcore.http.error.ResponseThrowable
import com.cn.appcore.utils.loader.LatteLoader
import rx.Subscription

/**
 * 项目：ForeignExchange
 * 包名：com.cn.appcore.base
 * 类名：BaseVMFragment
 * 创建时间：2022/10/3 16:19
 * 创建人 @author： xiaolin
 * 描述 ：Todo...
 */
abstract class BaseVMFragment <VM : BaseViewModel,T: ViewDataBinding>(@LayoutRes val layoutId: Int) : Fragment() {


    protected var pageNo=1
    protected var pageSize=10

    lateinit var mViewModel: VM
    lateinit var binding:T

    protected  fun < T : ViewDataBinding> binding(
        inflater: LayoutInflater,
        @LayoutRes layoutId: Int,
        container: ViewGroup?
    ): T =   DataBindingUtil.inflate<T>(inflater,layoutId, container,false).apply {
        lifecycleOwner = this@BaseVMFragment
    }


    abstract fun attachVMClass(): Class<VM>?
    /**  懒加载 **/
    abstract fun lazyLoad()
    protected abstract fun initView(savedInstanceState: Bundle?)


    //是否第一次加载
    protected open var isFirst: Boolean = true
    open var rxBusSubscription: Subscription? = null

    protected open var showLoadingDialog: Boolean = true
    private val loadingDialog by lazy { LatteLoader.getLoading(context) }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = binding(inflater,layoutId,container)
        return binding.root
    }
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        isFirst = true
        initVM()
        lifecycle.addObserver(mViewModel)
        initView(savedInstanceState)
        initData()
        initClickListener()
        initRequestObserver()
        initResultLauncher()
        lazyLoadDataIfPrepared()

    }

    /** 初始化数据 **/
    protected open fun initData() {}
    /** 设置事件监听 **/
    protected open fun initClickListener() {}
    /** 网络请求数据 **/
    protected open fun initRequestObserver() {}
    /** 页面跳转返回监听 **/
    protected open fun initResultLauncher() {}
    /** 注销页面跳转返回监听 **/
    protected open fun unregisterResultLauncher() {}
    protected open fun showLoading() {
        if (showLoadingDialog)
            LatteLoader.showLoading(loadingDialog)
    }

    protected open fun dismissLoading() {
        if (showLoadingDialog)
            LatteLoader.dismissLoading(loadingDialog)
    }
    protected open fun onError(error: ResponseThrowable) = Unit


    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if (isVisibleToUser) {
            lazyLoadDataIfPrepared()
        }
    }
    /**
     * 是否需要懒加载
     */
    private fun lazyLoadDataIfPrepared() {
        if (lifecycle.currentState == Lifecycle.State.STARTED && isFirst) {
            lazyLoad()
            isFirst = false
        }
    }
    private fun initVM() {
        if (attachVMClass() == null) {
            throw RuntimeException("ViewModel must not be null.")
        }
        attachVMClass()?.let {
//            mViewModel = ViewModelProviders.of(this).get(it)
            mViewModel= ViewModelProvider(this).get(it)
            lifecycle.addObserver(mViewModel)

        }
    }
    override fun onResume() {
        super.onResume()
        lazyLoadDataIfPrepared()
    }

    override fun onDestroy() {
        unregisterResultLauncher()
        lifecycle.removeObserver(mViewModel)
        rxBusSubscription?.unsubscribe()
        super.onDestroy()
    }

    /**
     * 跳转
     *
     * @param cls
     */
    protected open fun startActivity(cls: Class<*>?) {
        startActivity(cls, null)
    }

    /**
     * 跳转传参数
     *
     * @param cls
     * @param bundle
     */
    protected open fun startActivity(cls: Class<*>?, bundle: Bundle?) {
        val intent = Intent(activity, cls)
        if (bundle != null) {
            intent.putExtras(bundle)
        }
        startActivity(intent)
    }
}